﻿/* spi_comm.c */

#include "spi_comm.h"

/* 配置master interrupt mode. */

void spi_init_master(SPI_Type *base)
{
    CLOCK_EnableClock(kCLOCK_Spi0);

    spi_conf_master(base, eSPI_Speed_1843k, eSPI_CpolCpha_00, eSPI_BitOrder_MSB);

    base->DLY = 0u;
    base->STAT = base->STAT; /* clear flags. */

    /* enable interrupt. */
    base->INTENCLR = base->INTENSET; /* disable all interrupts first */
    base->INTENSET = SPI_INTENSET_RXRDYEN_MASK; /* only enable rx interrupt. */
    NVIC_EnableIRQ(SPI0_IRQn);
}

const uint8_t spi_baudrate_div[eSPI_Speed_None] = {7u, 31u, 63u, 127u};

void spi_conf_master(SPI_Type *base, spi_speed_t speed, spi_cpolcpha_t cpolcpha, spi_bitorder_t bitorder)
{
    uint32_t tmp32;

    /* master function. */
    tmp32 = SPI_CFG_ENABLE_MASK | SPI_CFG_MASTER_MASK;
    if ( ( eSPI_CpolCpha_01 == cpolcpha) || ( eSPI_CpolCpha_11 == cpolcpha) )
    {
        tmp32 |= SPI_CFG_CPHA_MASK;
        if ( eSPI_CpolCpha_11 == cpolcpha )
        {
            tmp32 |= SPI_CFG_CPOL_MASK;
        }
    }
    if ( eSPI_BitOrder_LSB == bitorder )
    {
        tmp32 |= SPI_CFG_LSBF_MASK;
    }
    base->CFG = tmp32;

    /* set bit rate. the clock source is main _clk, 15mhz*/
    base->DIV = spi_baudrate_div[speed];
}

void spi_master_start_xfer(SPI_Type *base, spi_master_xfer_handler_t *xfer_handler)
{
    xfer_handler->buff_index = 0u;

    base->TXDATCTL = SPI_TXDATCTL_TXDAT(xfer_handler->tx_buff[0])
                                      | SPI_TXDATCTL_LEN(7)
                                      //| SPI_TXDATCTL_EOF_MASK
                                      | SPI_TXDATCTL_EOT_MASK
                                      ;
}

void spi_master_isr_hook(SPI_Type *base, spi_master_xfer_handler_t *xfer_handler)
{
    uint32_t flags = base->INTSTAT;

    if (flags & SPI_INTSTAT_RXRDY_MASK)
    {
        xfer_handler->rx_buff[xfer_handler->buff_index++] = (uint8_t)base->RXDAT;

        if (xfer_handler->buff_index >= xfer_handler->buff_len)
        {
            if (xfer_handler->xfer_done_callback)
            {
                xfer_handler->xfer_done_callback( (void *)xfer_handler );
            }
        }
        else
        {
            base->TXDAT = xfer_handler->tx_buff[xfer_handler->buff_index];
        }
    }

    base->STAT = base->STAT; /* clear error flags. */
}



/* EOF. */

